/*
 * Copyright (C) 2021 NaviTech
 *
 * This file is subject to the terms and conditions of the GNU Lesser
 * General Public License v2.1. See the file LICENSE in the top level
 * directory for more details.
 */

/**
 * @ingroup     core_internal
 * @{
 *
  * @file         base_types.h
  * @brief        通过将不同的模块的错误码分段，在得到错误码之后，可以快速分析出返回错误的模块以及原因。
  * @note
  * @author       lixinliang
  * @date         2021-08-14
  *
  * @par          修改日志
  * <table>
  * <tr><th>Date        <th>Version          <th>Author                        <th>Description
  * <tr><td>2021-08-14  <td>1.0              <td>lixinliang@hopechart.com      <td>创建初始版本
  * @copyright
  */
#ifndef _SFC_MEM_FIFO_H_
#define _SFC_MEM_FIFO_H_

#include "base_types/base_types.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef struct TSFCMemFifoTag
{
    void     *buff;  ///< FIFO buffer
    uint32_t buff_size;   ///< FIFO buffer size
    uint32_t rd;     ///< FIFO read pointer
    uint32_t wr;     ///< FIFO write pointer
} TSFCMemFifo;

bool TSFCMemFifoCreate(TSFCMemFifo *self, void *buff, uint32_t buff_size);

void TSFCMemFifoDestroy(TSFCMemFifo *self);

int32_t TSFCMemFifoPut(TSFCMemFifo *self, const void *data, uint32_t data_size);

int32_t TSFCMemFifoGet(TSFCMemFifo *self, void *buff, uint32_t buff_size);

int32_t TSFCMemFifoPeek(TSFCMemFifo *self, void *buff, uint32_t buff_size);

/**
 * @brief   删除FIFO中指定字节数
 *
 * 当 @p skip_size 大于FIFO中的 @p TSFCMemFifoBytes 实际字节数，则删除数量为实际字节数
 *
 * @param[in] self       FIFO 操作对象
 * @param[in] skip_size  指定的删除字节数
 * @return 实际删除的字节数
 */
int32_t TSFCMemFifoSkipBytes(TSFCMemFifo *self, uint32_t skip_size);

/**
 * @brief   清除FIFO中的数据
 *
 * @param[in] self  FIFO 操作对象
 */
void TSFCMemFifoReset(TSFCMemFifo *self);

/**
 * @brief   search a byte in FIFO
 *
 * 在查询的过程中，那些不匹配的字节将会被从FIFO中删除掉，直到遇到该字符停止。
 * 当遇到查询的 @p byte， 可以通过 @p keep 指定是否删除
 *
 * @param[in] self  FIFO 操作对象
 * @param[in] byte  待查找的字符
 * @param[in] keep  true: 保留查找的字符，false: 删除查找的字符，并停止
 * @return
 *      - true if @p byte 被查找到
 *      - false if @p byte 未查找到
 */
bool TSFCMemFifoSearch(TSFCMemFifo *self, uint8_t byte, bool keep);

static inline size_t TSFCMemFifoBytes(TSFCMemFifo *self) { return self->wr - self->rd; }

static inline size_t TSFCMemFifoSpace(TSFCMemFifo *self) { return self->size - TSFCMemFifoBytes(self); }

static inline bool TSFCMemFifoIsFull(TSFCMemFifo *self) { return TSFCMemFifoSpace(self) == 0; }

static inline bool TSFCMemFifoIsEmpty(TSFCMemFifo *self) { return TSFCMemFifoBytes(self) == 0; }

#ifdef __cplusplus
} // extern "C" {
#endif

#endif	// _SFC_MEM_FIFO_H_
